![TypeScript(Node.js)のバリデーションライブラリ「Ajv」を使ってみた](https://devio2023-media.developers.io/wp-content/uploads/2019/04/ts-eyecatch.png)
TypeScript(Node.js)のバリデーションライブラリ「Ajv」を使ってみた
Ajv(Another JSON Schema Validator)はNode.jsとブラウザ用のバリデーションライブラリです。事前に定義した検証スキーマでデータのバリデーションを行います。また、バリデーションエラーの内容はerrors
プロパティに格納され、バリデーション後に取得することができます。
基本的な使い方
Ajvのインストールとバリデーションの方法を説明します。
インストール
npm(Node package manager)でインストールします。なお、型情報も組み込まれているため@types/ajv
は必要ありません。
npm install ajv
バリデーションを実行
検証スキーマと検証データを定義してバリデーションを実行してみます。
import Ajv from 'ajv'; // インスタンスを作成 const ajv = new Ajv(); // 検証スキーマを定義 const schema = { required: ['name', 'email'], type: 'object', properties: { name: { type: 'string', }, email: { type: 'string', format: 'email', maxLength: 50, }, age: { type: 'integer', }, }, }; // 検証データを定義 const data = { name: '田中太郎', email: 'test', age: 26, }; // バリデーション関数を作成 const validate = ajv.compile(schema); // バリデーションを実行 const valid = validate(data); if (!valid) { // バリデーションエラー console.log(validate.errors); }
次のエラーがコンソールに出力されます。
[ { keyword: 'format', dataPath: '.email', schemaPath: '#/properties/email/format', params: { format: 'email' }, message: 'should match format "email"' } ]
バリデーションの種類
良く使うバリデーションの種類を紹介します。
type
データが特定の型(number
, integer
, string
, boolean
, array
, object
, null
)であることを検証します。また、配列でいずれかの型を検証することもできます。
const validate = ajv.compile({ type: 'string' }); validate('田中太郎'); // true validate(100); // false
maxLength, minLength
文字列の長さを検証します。
const validate = ajv.compile({ maxLength: 4 }); validate('あいうえ'); // true validate('あいうえお'); // false
maximum, minimum
数値の大きさを検証します。
const validate = ajv.compile({ maximum: 4 }); validate(4); // true validate(5); // false
properties
オブジェクトプロパティの有効性を検証します。ただし、スキーマ定義したプロパティがオブジェクトに存在しない場合も、バリデーションの結果はtrue
を返します。
const validate = ajv.compile({ properties: { foo: { type: 'string' }, bar: { type: 'number', minimum: 2, }, }, }); validate({ foo: 'a', bar: 2 }); // true validate({ foo: 'a' }); // true validate({ foo: 'a', bar: 1 }); // false
required
オブジェクトに指定したプロパティが存在することを検証します。
const validate = ajv.compile({ required: ['foo', 'bar'], properties: { foo: { type: 'string' }, bar: { type: 'number', minimum: 2, }, }, }); validate({ foo: 'a', bar: 2 }); // true validate({ foo: 'a' }); // false validate({ foo: 'a', bar: 1 }); // false
pattern
文字列を正規表現で検証します。文字列以外を指定した場合はtrue
を返します。
const validate = ajv.compile({ pattern: '[abc]+' }); validate('abcd'); // true validate(1); // true validate(null); // true validate('def'); // false validate(''); // false
format
文字列を既存のフォーマットで検証します。文字列以外を指定した場合はtrue
を返します。
const validate = ajv.compile({ format: 'date' }); validate('2020-04-07'); // true validate(1); // true validate(null); // true validate('abc'); // false validate(''); // false
フォーマット
バリデーションのformat
で指定できる形式は次のとおりです。
項目 | 説明 | 例 |
---|---|---|
date | 日付(RFC3339に準拠) | 2020-04-07 |
time | 時間 | 23:59:59 |
date-time | 日時 | 2020-04-07 23:59:59 |
uri | 完全なURI | file:///User/admin/Desktop/test.json |
uri-reference | 相対URIを含むURI | Desktop/test.json |
uri-template | URIテンプレート(RFC6570に準拠) | http://www.example.com/foo?number=100 |
url | URLレコード(非推奨) | http://example.com |
メールアドレス | test@example.com | |
hostname | ホスト名(RFC1034に準拠) | example.com |
ipv4 | IPv4アドレス | 192.168.0.1 |
ipv6 | IPv6アドレス | ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 |
regex | 正規表現 | [abc]+ |
uuid | 一意の識別子(RFC4122に準拠) | 817dc001-06ef-4400-a85b-116015cbb7b7 |
json-pointer | JSON pointer(RFC6901に準拠) | /foo |
relative-json-pointer | JSON Resolve pointer |
まとめ
Pythonで開発をしていた際には、Cerberusというバリデーションライブラリを導入していました。TypeScriptを採用した開発でも、Ajvで同じようにスキーマを定義してバリデーションができたのでとても使いやすく感じました。既にJSONデータが手元にある場合には、quicktypeというツールでスキーマを生成すると楽ができると思います。